package com.crazy.util;

import org.springframework.util.StringUtils;
import sun.misc.BASE64Decoder;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

/**
 * @author panyonghui
 * @describe 文件处理工具类
 * @date 2022/1/14 15:21
 */
public class FileUtils {
    /**
     * 字符串转成文件
     *
     * @param filePath 文件保存路径（/home/file/test.txt）
     * @param str      字符串
     * @param encoding 编码
     * @param isAppend 是否在原有文件上续写
     * @throws IOException
     */
    public static void str2File(String filePath, String str, String encoding, boolean isAppend) throws IOException {
        if (filePath != null) {
            File completeFile = new File(filePath);
            String path = filePath.replace(completeFile.getName(), "");
            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }
            try (OutputStream os = new FileOutputStream(completeFile, isAppend);
                 Writer osw = new OutputStreamWriter(os, encoding)) {
                BufferedWriter bw = new BufferedWriter(osw);
                bw.write(str);
                bw.flush();
            }
        }
    }

    /**
     * 文件转成字符串
     * @param filePath 文件路径(/home/file/test.txt)
     * @param encoding 字符串编码
     * @param lineChar 换行符(无须换行送null即可)
     * @return 文本内容
     * @throws IOException
     */
    public static String readFile2Str(String filePath, String encoding, String lineChar) throws IOException {
        StringBuffer fileStrBuff = new StringBuffer();
        File file = new File(filePath);
        try(FileInputStream fis = new FileInputStream(file);
            InputStreamReader isr = new InputStreamReader(fis, encoding);
            BufferedReader br = new BufferedReader(isr);
        ){
            String line;
            while((line = br.readLine()) != null){
                fileStrBuff.append(line);
                if (lineChar != null) {
                    fileStrBuff.append(lineChar);
                }
            }
        } catch (IOException e){
            throw e;
        }
        return fileStrBuff.toString();
    }

    /**
     * base64转文件
     * @param base64 文件的base64
     * @param filePath 文件保存路径(/home/file/test.pdf）)
     */
    public static void base64ToFile(String filePath, String base64) throws IOException {
        File file = new File(filePath);
        // 文件路径
        String relativePath = StringUtils.applyRelativePath(filePath, "");
        File path = new File(relativePath);
        // 文件路径不存在则创建
        if (!path.exists()){
            path.mkdirs();
        }
        try (OutputStream fos = new FileOutputStream(file)) {
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] by = decoder.decodeBuffer(base64);
            fos.write(by);
            fos.flush();
        } catch (IOException e) {
            throw e;
        }
    }

    /**
     * @describe 文件转字节流
     * @param pdfPath
     * @return byte[]
     * @modify
     */
    public static byte[] fileToBytes(String pdfPath) throws IOException {
        File file = new File(pdfPath);
        try(FileInputStream inputStream = new FileInputStream(file);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(bytes)) != -1){
                outputStream.write(bytes, 0, len);
            }
            outputStream.flush();
            return outputStream.toByteArray();
        } catch (IOException e){
            throw e;
        }
    }

    /**
     * @describe 字节流转文件
     * @param filePath
     * @param data
     * @return void
     * @modify
     */
    public static void bytesToFile(String filePath, byte[] data) throws IOException {
        try(FileOutputStream fileOutputStream = new FileOutputStream(filePath);) {
            fileOutputStream.write(data);
            fileOutputStream.flush();
        } catch (IOException e){
            throw e;
        }
    }
}